package model.semantics;

import java.util.ArrayList;
import java.util.Collection;

import model.RGBColor;


/**
 * Defines a general method for combining colors together.
 * 
 * @author Robert C Duvall
 */
public abstract class AbstractToken
{
    protected Collection<AbstractToken> myChildren;
	protected int myPrecedence;

	// TODO: abstract token doesn't need number of arguments
	//     but should have precedence passed
	// num of arguments is stupid because kind of point of binary & unary classes
	// precedence shouldn't be set within each class
	// also only operationtoken needs num of arguments
	// - can also move leftAssociative down to with num of args
	// 
	// should we consider moving myChildren to operationToken?
	
    /**
     * Create a Token that has the given precedence
     */
    public AbstractToken (int precedence)
    {
    	myPrecedence = precedence;
        myChildren = new ArrayList<AbstractToken>();
    }
    
    /**
     * Return precedence of operator.
     * @return
     */
    public int getPrecedence()
    {
    	return myPrecedence;
    }
    
    /**
     * Compare the precedence of two operators.
     * Return a negative integer if token 1's precedence < token 2's precedence.
     * Return 0 if the two precedences are equal.
     * Return a positive integer otherwise.
     */
    public int comparePrecedence(AbstractToken nodeToCompare)
    {
    	return myPrecedence - nodeToCompare.getPrecedence();
    }
    
    public abstract boolean addChild(AbstractToken o);
    
    public abstract Collection<AbstractToken> getChildren();


    /**
     * Given any number of colors, combine them to create a single color.
     */
    public RGBColor evaluate (RGBColor ... colors)
    {
        return evaluateSafely(colors);
    }
    
    /**
     * Provide subclasses a safe version of evaluate.
     * 
     * This version is guaranteed to have the correct number of arguments. 
     */
    protected abstract RGBColor evaluateSafely (RGBColor[] colors);

}
